// Oliver Shyal Beardsley
// 17/2/2011

//! Card class declaration

#ifndef _CARD_H_
#define _CARD_H_

#include "Item.h"

#include <algorithm>
#include <set>
#include <QString>
#include <QUuid>
#include <QVector>
#include <QPair>
#include <QDateTime>

typedef time_t time_span_ms;

class Card : public Item
{
private:

	typedef QVector<time_t> TimeContainer;
	typedef QVector<time_span_ms> TimeSpanContainer;

	public:

		enum Side
		{
			eFRONT,
			eBACK
		};

		//friend QDataStream 	&operator<<( QDataStream &stream, const Card &data );
		//friend QDataStream 	&operator>>( QDataStream &stream, Card &data );

		void				readVer1(QDataStream& stream);
		void				readVer2(QDataStream& stream);

		void				writeCurrentVer(QDataStream& stream) const;

		Card();

		//! class destructor
		~Card();

		virtual void			setQuestion(const QString&);
		void					setAnswer(const QString&);

		virtual QString		getQuestion() const;
		QString				getAnswer() const;
		int					getTimesAnsweredCorrectly() const;
		int					getTimesAnsweredCorrectlyLastInSuccession() const;
		int					getTimesDisplayed(time_t atTime = -1) const;
		int					getLastDisplayed() const;
		int					getAge() const;
		int					getFirstDisplayed() const;

		bool					isDue(long int t = 0) const;

		int					getDueDate() const;

		bool					getWasSuccessfullyAnsweredAtLeastOnce(int atTime = -1) const;

		bool					getLastDisplayWasSuccess() const;

		int					getSlot() const;

		void					setDisplayed(bool displayed = true);

		void					setKnewIt();

		float				getDisplayEase(int atTime = -1) const;
		float				getAnswerEase(int atTime = -1) const;

		int					getTimesAnsweredWrong() const;

		bool					isNew() const;

		// reset the history of this card.
		// this the card into a new card (as if it were never viewed or touched)
		void					reset();

		unsigned int			getNumTimesViewed() const;

		bool					isNull() const;

		// order based on due date
		struct Comp
		{
			bool				operator()(Card, Card);
		};

		// the more a card has been displayed while remaining unanswered
		// the harder it is
		struct DisplayEase
		{
			bool				operator()(Card, Card);
		};

		// the more a card has been unanswerd incorrectly
		// the harder it is
		struct AnswerEase
		{
			bool				operator()(Card, Card);
		};

		QUuid				getQuestionAudio() const;
		QUuid				getAnswerAudio() const;

		void					setQuestionAudio(QUuid);
		void					setAnswerAudio(QUuid);

		void					setIsPersistent(bool);
		bool					getIsPersistent() const;

		void					print();

		void					registerTimeToAnswerMs(time_span_ms durationMs);

	private:


	private:
		QString					m_question;
		QString					m_answer;
		TimeContainer			m_displayedDate; //changed from int
		QVector<bool>			m_remembered;
		bool					m_isNull;
		QUuid					m_questionAudio;
		QUuid					m_answerAudio;
		bool					m_persistent;
		TimeSpanContainer		m_timeTaken; //seconds as m_pDispayedDate
};

#endif
